using System;
using System.Collections;
using Sedna.Core.Persistence;
using Iesi.Collections;
using NHibernate;

namespace Sedna.DAO
{
	public interface IBaseDAO
	{
		object GetById(Type type, object id);

        /// <summary>
        /// Checks if entity isn't attached to the session
        /// </summary>
        bool Contains(object entity);

        void SaveOrUpdate(object entity);

        /// <summary>
        /// Calls <see cref="ISession.Update(object)"/> without checking first
        /// </summary>
        void Update(object detachedEntity);

        /// <summary>
        /// Checks if entity isn't attached to the session
        /// and calls <see cref="ISession.Update(object)"/>
        /// </summary>
        void TryToUpdate(object entity);

        /// <summary>
        /// Calls <see cref="ISession.Refresh(object)"/>
        /// </summary>
        void Refresh(object entity);

		/// <summary>
		/// deletes an entity by direct calling to ISession.Delete(object)
		/// this means that the objec must be a valid persistent, previously saved object.
		/// a more effective way of deleting an object is by means of the Delete(Type, object)
		/// which executes a direct HQL query (which in its turn is mapped into SQL DELETE ... WHERE statement)
		/// </summary>
		/// <param name="entity"></param>
		void Delete(object entity);


		/// <summary>
		/// deletes a persistent object by means of a HQL query.
		/// this method is idempontent and can be called multiple times for the same entity.
		/// if a persistent object has already been deleted nothing happens, the method runs a corresponding 
		/// SQL DELETE ... WHERE statement and returns without any error
		/// </summary>
		/// <param name="type">persistent type (normally one of the Domain objects)</param>
		/// <param name="id">valid identifier of an object to delete, can be any valid object identifier type, including int and string</param>
		void Delete(Type type, object id);

	    /// <summary>
        /// Attaches an object or a collection of objects to session.
        /// Returns amount of attached objects.
	    /// </summary>
        int AttachToSession(Object entity);        

        FlushMode SetSessionNoFlush();

        void RestoreSessionFlushMode(FlushMode flushMode);
	}
}
